import { imaAdpcmDecode } from './ima-adpcm.js';

function hexStringToUint8Array(hex) {
  if (hex.length % 2 !== 0) hex = hex.slice(0, -1);
  const arr = new Uint8Array(hex.length / 2);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = parseInt(hex.substr(i * 2, 2), 16);
  }
  return arr;
}

export function pcmToWav(pcm, sampleRate = 8000) {
  console.log('[ADPCM] pcmToWav 输入:', { pcmLength: pcm.length, sampleRate });
  
  if (!pcm || pcm.length === 0) {
    console.error('[ADPCM] pcmToWav: 输入PCM数据为空');
    return null;
  }
  
  try {
    const buffer = new ArrayBuffer(44 + pcm.length * 2);
    const view = new DataView(buffer);
    
    function writeString(view, offset, string) {
      for (let i = 0; i < string.length; i++) {
        view.setUint8(offset + i, string.charCodeAt(i));
      }
    }
    
    writeString(view, 0, 'RIFF');
    view.setUint32(4, 36 + pcm.length * 2, true);
    writeString(view, 8, 'WAVE');
    writeString(view, 12, 'fmt ');
    view.setUint32(16, 16, true);
    view.setUint16(20, 1, true);
    view.setUint16(22, 1, true);
    view.setUint32(24, sampleRate, true);
    view.setUint32(28, sampleRate * 2, true);
    view.setUint16(32, 2, true);
    view.setUint16(34, 16, true);
    writeString(view, 36, 'data');
    view.setUint32(40, pcm.length * 2, true);
    
    for (let i = 0; i < pcm.length; i++) {
      view.setInt16(44 + i * 2, pcm[i], true);
    }
    
    console.log('[ADPCM] pcmToWav 生成WAV数据成功，大小:', buffer.byteLength);
    
    // #ifdef H5
    return new Blob([buffer], { type: 'audio/wav' });
    // #endif
    
    // #ifdef APP-PLUS
    return buffer;
    // #endif
  } catch (error) {
    console.error('[ADPCM] pcmToWav 生成WAV数据失败:', error);
    return null;
  }
}

class AdpcmFrameDecoder {
  constructor(sampleRate = 8000) {
    this.sampleRate = sampleRate;
    this.adpcmBuffer = [];
    this.pcmBuffer = null;
    this.pcmBlobUrl = '';
    this.status = '';
    // 添加解码状态
    this.decoderState = {
      last: 0,
      stepIndex: 0
    };
  }

  // 传入蓝牙帧对象 { value: '55aa...' }
  pushFrame(frame) {
    console.log('[ADPCM] pushFrame 入参:', frame);
    const bytes = typeof frame.value === 'string' ? hexStringToUint8Array(frame.value) : frame.value;
    console.log('[ADPCM] pushFrame 解析 bytes:', bytes);
    // 新增：打印16进制字符串（前100字节）
    const hexStr = Array.from(bytes.slice(0, 100)).map(b => b.toString(16).padStart(2, '0')).join(' ');
    console.log('[ADPCM] pushFrame 解析 bytes hex(前100字节):', hexStr);
    
    if (bytes[0] !== 0x55 || bytes[1] !== 0xAA) {
      this.status = '帧头错误';
      console.log('[ADPCM] 帧头错误:', bytes);
      return null;
    }
    
    const frameType = bytes[3];
    const audioLen = bytes[4];
    const adpcmData = bytes.slice(5, 5 + audioLen);
    console.log(`[ADPCM] 收到帧: type=0x${frameType.toString(16)}, audioLen=${audioLen}, adpcmData.length=${adpcmData.length}`);
    
    let realtimePcmData = null;
    
    if (frameType === 0x00) {
      // 首帧：保存初始状态
      if (adpcmData.length >= 4) {
        this.decoderState.last = adpcmData[0] | (adpcmData[1] << 8);
        this.decoderState.stepIndex = adpcmData[2];
        console.log('[ADPCM] 首帧状态:', this.decoderState);
        this.adpcmBuffer = Array.from(adpcmData.slice(4));
      } else {
        console.error('[ADPCM] 首帧数据长度不足');
        return null;
      }
      this.status = '收到首帧';
      console.log('[ADPCM] 收到首帧, adpcmBuffer.length:', this.adpcmBuffer.length);
    } else if (frameType === 0x01) {
      this.adpcmBuffer = this.adpcmBuffer.concat(Array.from(adpcmData));
      this.status = '收到中间帧';
      console.log('[ADPCM] 收到中间帧, adpcmBuffer.length:', this.adpcmBuffer.length);
      // 对中间帧进行实时解码
      realtimePcmData = this.decodeRealtimeFrame(adpcmData);
    } else if (frameType === 0x02) {
      this.adpcmBuffer = this.adpcmBuffer.concat(Array.from(adpcmData));
      this.status = '收到结束帧，开始解码';
      console.log('[ADPCM] 收到结束帧, adpcmBuffer.length:', this.adpcmBuffer.length);
      // 对结束帧进行实时解码
      realtimePcmData = this.decodeRealtimeFrame(adpcmData);
    } else {
      this.status = `未知帧类型: 0x${frameType.toString(16)}`;
      console.log('[ADPCM] 未知帧类型:', frameType, bytes);
    }
    console.log('[ADPCM] 当前状态:', this.status);
    return realtimePcmData;
  }

  // 实时解码当前帧
  decodeRealtimeFrame(adpcmData) {
    try {
      // 使用当前状态进行解码
      const pcmData = imaAdpcmDecode(new Uint8Array(adpcmData), this.decoderState);
      if (pcmData && pcmData.length > 0) {
        console.log('[ADPCM] 实时解码完成，当前PCM数据长度:', pcmData.length);
        return pcmData;
      }
    } catch (error) {
      console.error('[ADPCM] 实时解码当前帧失败:', error);
    }
    return null;
  }

  // 解码所有累积的数据
  decodeAllFrames() {
    try {
      if (this.adpcmBuffer.length === 0) {
        console.log('[ADPCM] 没有数据需要解码');
        return null;
      }

      // 使用保存的初始状态进行解码
      const pcmData = imaAdpcmDecode(new Uint8Array(this.adpcmBuffer), this.decoderState);
      if (pcmData && pcmData.length > 0) {
        console.log('[ADPCM] 全部解码完成，PCM数据长度:', pcmData.length);
        return pcmData;
      }
    } catch (error) {
      console.error('[ADPCM] 解码所有数据失败:', error);
    }
    return null;
  }

  // 获取播放URL
  getPcmBlobUrl() {
    console.log('[ADPCM] getPcmBlobUrl:', this.pcmBlobUrl);
    return this.pcmBlobUrl;
  }

  // 获取状态，优先返回解码完成
  getStatus() {
    console.log('[ADPCM] getStatus:', this.status);
    if (this.status === '解码完成，可播放') return this.status;
    return this.status;
  }

  // 清理
  reset() {
    console.log('[ADPCM] reset, 清理缓存');
    this.adpcmBuffer = [];
    this.pcmBuffer = null;
    if (this.pcmBlobUrl) {
      console.log('[ADPCM] 释放pcmBlobUrl');
      URL.revokeObjectURL(this.pcmBlobUrl);
    }
    this.pcmBlobUrl = '';
    this.status = '';
    // 重置解码状态
    this.decoderState = {
      last: 0,
      stepIndex: 0
    };
  }
}

export default AdpcmFrameDecoder; 